using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Comteck.Dto.Sys;
using Comteck.Ktt.Services.Sys;
using Comteck.Winforms.Dialog;
using Comteck.Winforms.Utils;
using DevExpress.XtraPrinting;
using FastReport;
using FastReport.Export;
using FastReport.Export.Image;
using FastReport.Export.OoXML;
using Microsoft.Extensions.DependencyInjection;

namespace Comteck.Winforms.Data {
  /// <summary>
  /// 本地数据库帮助类 [fastreport]
  /// </summary>
  public partial class LocalDbDataHelper {

    #region 公用方法

    /// <summary>
    /// 登录信息的参数赋值
    /// </summary>
    private static void SetParametertLoginInfo(Report report) {
      report.SetParameterValue("Login_Code", SysGlobal.LoginUser.Id);
      report.SetParameterValue("Login_Name", SysGlobal.LoginUser.Name);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="exportTarget"></param>
    /// <returns></returns>
    private static ExportBase GetFastReportExportBase(ExportTarget exportTarget) {
      ExportBase exportBase = null;

      switch (exportTarget) {
        case ExportTarget.Xls:
        case ExportTarget.Xlsx:
          exportBase = new Excel2007Export() { };
          break;
        case ExportTarget.Pdf:
          break;
        case ExportTarget.Html:
          break;
        case ExportTarget.Text:
          break;
        case ExportTarget.Mht:
          break;
        case ExportTarget.Rtf:
          break;
        case ExportTarget.Csv:
          break;
        case ExportTarget.Image:
          exportBase = new ImageExport() {
            ImageFormat = FastReport.Export.Image.ImageExportFormat.Png
          };
          break;
        default:
          break;
      }

      return exportBase;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="exportType"></param>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public static (bool, string) OpenFileDialog(ExportTarget exportType = ExportTarget.Xlsx, string fileName = null, string initialDirectory = null) {
      // 初始化对话框
      var saveDialog = new SaveFileDialog();
      saveDialog.Title = "导出文件";
      saveDialog.FileName = fileName;
      saveDialog.InitialDirectory = initialDirectory;
      switch (exportType) {
        case ExportTarget.Xls:
          saveDialog.Filter = "Excel文件(*.xls)|*.xls";
          break;
        case ExportTarget.Xlsx:
          saveDialog.Filter = "Excel文件(*.xlsx)|*.xlsx";
          break;
        case ExportTarget.Csv:
          saveDialog.Filter = "CSV文件(*.csv)|*.csv";
          break;
        case ExportTarget.Pdf:
          saveDialog.Filter = "PDF文件(*.pdf)|*.pdf";
          break;
        case ExportTarget.Html:
          saveDialog.Filter = "HTML文件(*.html)|*.html";
          break;
        case ExportTarget.Text:
          saveDialog.Filter = "文本文件(*.txt)|*.txt";
          break;
        case ExportTarget.Mht:
          saveDialog.Filter = "MHT文件(*.mht)|*.mht";
          break;
        case ExportTarget.Rtf:
          saveDialog.Filter = "RTF文件(*.rtf)|*.rtf";
          break;
        case ExportTarget.Image:
          saveDialog.Filter = "PNG文件(*.png)|*.png";
          break;
        //case EnumExportFileType.IMG:
        //  saveDialog.Filter = "图像文件(*.JPEG)|*.JPEG | 图像文件(*.JPG)|*.JPG | 图像文件(*.PNG)| *.PNG";
        //  break;
        default:
          break;
      }

      // 打开对话框
      var dialogResult = saveDialog.ShowDialog();

      // 取消
      if (dialogResult == DialogResult.Cancel) {
        return (false, null);
      }

      // 没有选择文件
      if (string.IsNullOrWhiteSpace(saveDialog.FileName)) {
        DevHelper.ShowMsg("请输入导出文件的名称");
        return (false, null);
      }

      return (true, saveDialog.FileName);
    }

    /// <summary>
    /// 打开文件
    /// </summary>
    /// <param name="filePath"></param>
    private static void OpenFileAction(bool openFile, string filePath) {
      if (openFile) {
        var dialog = DevHelper.ShowMsg("文件保存成功！{0}您现在是否要打开该文件？".FormatWith(Environment.NewLine),
          "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

        if (dialog == DialogResult.No) {
          return;
        }

        try {
          var process = new System.Diagnostics.Process();
          process.StartInfo.FileName = filePath;
          process.StartInfo.Verb = "Open";
          process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
          process.Start();
        } catch {
          DevHelper.ShowMsg("打开失败，请检查是否已安装相应的软件！");
        }
      } else {
        DevHelper.ShowMsg("文件保存成功");
      }
    }

    #endregion

    #region 打开通用打印对话框(支持单字段)

    /// <summary>
    /// 打开通用打印对话框(支持单字段)
    /// <para>如果只有一条记录，则直接打印预览，否则就打开对话框</para>
    /// </summary>
    /// <param name="menuId">菜单ID</param>
    /// <param name="printList">待打印的数据集合：int或string的泛型</param>
    public static async Task<bool> OpenPrintDialog(string menuId, List<dynamic> printList, bool directPrint = false) {
      if (menuId.IsNullOrEmpty()) {
        DevHelper.ShowMsg("菜单ID不能为空！");
        return false;
      }

      // 去服务端查找对应的菜单数据
      var templates = await SysGlobal.ServiceProvider.GetRequiredService<IPrintTemplateService>().GetListByMenuIdAsync(menuId, 1);
      if (templates.IsNullOrEmpty()) {
        DevHelper.ShowMsg("该菜单对应的有效打印模板不存在");
        return false;
      }

      // 只有一个模板不弹出选择模板对话框
      if (templates.Count == 1) {
        return await Print(templates.First(), printList, directPrint);
      } else {
        var form = new FrmPrintDialog {
          PrintList = printList
        };
        form.BindData(templates);
        form.ShowDialog();
        return true;
      }
    }

    /// <summary>
    /// 打印模板
    /// </summary>
    /// <param name="entity"></param>
    /// <param name="printList"></param>
    public static async Task<bool> Print(PrintTemplateDto entity, List<dynamic> printList, bool directPrint = false) {
      var flag = false;

      if (IsExecuting) {
        return flag;
      }
      IsExecuting = true;

      try {
        var result = await ServerDbDataHelper.GetPrintTemplatePrintDataSource(entity.Id, printList);

        if (result.Code != 1) {
          var msg = $"查询菜单模板失败，{result.Message}";
          Logger.Error(msg);
          DevHelper.ShowMsg(msg);
          return flag;
        }

        using (var report = new Report()) {
          report.LoadFromString(entity.Data);
          // 登录信息的参数赋值
          SetParametertLoginInfo(report);
          report.RegisterData(result.Data);
          report.Show();
        }
        flag = true;
      } catch (Exception ex) {
        IsExecuting = false;
        throw ex;
      } finally {
        IsExecuting = false;
      }

      return flag;
    }

    #endregion

    #region 直接导出

    /// <summary>
    /// 直接导出
    /// </summary>
    /// <param name="entity"></param>
    /// <param name="printList"></param>
    /// <param name="exportTarget"></param>
    public static async void Export(PrintTemplateDto entity, List<dynamic> printList, string fileName = null, bool openFile = true,
      ExportTarget exportTarget = ExportTarget.Xlsx, string initialDirectory = null) {
      if (IsExecuting) return;
      IsExecuting = true;

      try {
        var result = await ServerDbDataHelper.GetPrintTemplatePrintDataSource(entity.Id, printList);

        if (result.Code != 1) {
          var msg = $"查询菜单模板失败，{result.Message}";
          Logger.Error(msg);
          DevHelper.ShowMsg(msg);
          return;
        }

        // 获取导出文件路径
        var openFileResult = OpenFileDialog(exportTarget, fileName, initialDirectory);

        // return
        if (openFileResult.Item1 == false) {
          return;
        }

        using (var report = new Report()) {
          // 加载数据
          report.LoadFromString(entity.Data);
          // 登录信息的参数赋值
          SetParametertLoginInfo(report);
          report.RegisterData(result.Data);

          // 加载数据
          report.PrintSettings.ShowDialog = false;
          report.Prepare();

          // 导出
          using (var exportBase = GetFastReportExportBase(exportTarget)) {
            report.Export(exportBase, openFileResult.Item2);
          }
        }

        // 打开文件
        OpenFileAction(openFile, openFileResult.Item2);

      } catch (Exception ex) {
        IsExecuting = false;
        throw ex;
      } finally {
        IsExecuting = false;
      }
    }

    #endregion

  }
}
